package com.example.util;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class Transform {
    public static int width;
    public static int height;
    public static String path="src\\main\\resources\\static\\dicePhoto\\";//骰子图片存储位置
    public static  String src="src\\main\\resources\\static\\image\\touzi\\";//
    /**
     * 保存图片的方法
     * @param buffImg
     * @param savePath 保存图片的路径
     */
    public static void generateSaveFile(BufferedImage buffImg, String savePath) {
        int temp = savePath.lastIndexOf(".") + 1;
        try {
            BufferedWriter bw = new BufferedWriter(new FileWriter(savePath));
            File outFile = new File(savePath);
            ImageIO.write(buffImg, savePath.substring(temp), outFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     *
     * @param img1 待合并图片
     * @param img2 骰子图片1-6
     * @param isHorizontal
     * @return
     * @throws IOException
     */
    public static BufferedImage mergeImage(BufferedImage img1,
                                           BufferedImage img2, boolean isHorizontal) throws IOException {
        int w1 = img1.getWidth();
        int h1 = img1.getHeight();
        int w2 = img2.getWidth();
        int h2 = img2.getHeight();

        // 从图片中读取RGB
        int[] ImageArrayOne = new int[w1 * h1];
        ImageArrayOne = img1.getRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); //逐行扫描图像中各个像素的RGB到数组中
        int[] ImageArrayTwo = new int[w2 * h2];
        ImageArrayTwo = img2.getRGB(0, 0, w2, h2, ImageArrayTwo, 0, w2); //逐行扫描图像中各个像素的RGB到数组中

        // 生成新图片
        BufferedImage DestImage = null;
        if (isHorizontal) { // 水平方向合并
            DestImage = new BufferedImage(w1 + w2, h1, BufferedImage.TYPE_INT_RGB);
            DestImage.setRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB
            DestImage.setRGB(w1, 0, w2, h2, ImageArrayTwo, 0, w2);
        } else { // 垂直方向合并
            DestImage = new BufferedImage(w1, h1 + h2, BufferedImage.TYPE_INT_RGB);
            DestImage.setRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB
            DestImage.setRGB(0, h1, w2, h2, ImageArrayTwo, 0, w2); // 设置下半部分的RGB
        }
        return DestImage;//返回转换后的骰子图
    }


    /**
     * @param img1  待合并图片1
     * @param bi2  骰子图片1-6
     * @param state true垂直合并 ,false水平
     * @param k     第k列图片
     **/
    public static String imageMargeTest(String img1, int k, BufferedImage bi2, boolean state) {

        // 读取待合并的文件
        BufferedImage bi1 = null;

        try {
            bi1 = ImageIO.read(new FileInputStream(img1));
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 调用mergeImage方法获得合并后的图像
        BufferedImage destImg = null;
        try {
            // 调用mergeImage方法获得合并后的图像
            destImg = mergeImage(bi1, bi2, state);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 保存图像
        generateSaveFile(destImg, path + k + ".jpg");
        return path + k + ".jpg";
    }


    public static List ReadRgb(String img) {
        int[] rgb = new int[3];
        File file = new File(img);
        BufferedImage bi = null;
        try {
            bi = ImageIO.read(file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        width = bi.getWidth();
        height = bi.getHeight();
        int minx = bi.getMinX();
        int miny = bi.getMinY();
//        System.out.println("width="+width+",height="+height+".");
//        System.out.println("minx="+minx+",miniy="+miny+".");
        double sum;
        List<Double> list = new ArrayList<>(width * height);//一张照片要存放的像素点的个数
        for (int i = minx; i < width; i++) {
            for (int j = miny; j < height; j++) {
                int pixel = bi.getRGB(i, j);
                rgb[0] = (pixel & 0xff0000) >> 16;
                rgb[1] = (pixel & 0xff00) >> 8;
                rgb[2] = (pixel & 0xff);
//                System.out.println("("+rgb[0]+","+rgb[1]+","+rgb[2]+")");
                sum = (rgb[0] + rgb[1] + rgb[2]) / 3;
                list.add(sum);
            }
        }
        return list;
    }

    static class replace extends Thread {
        List<Double> list;
        int i1;

        public replace(java.util.List<Double> list,int i1){
            this.list = list;
            this.i1 = i1;
        }

        @Override
        public void run() {
            BufferedImage img1 = null, img2 = null, img3 = null, img4 = null, img5 = null, img6 = null;
            try {
                img1 = ImageIO.read(new FileInputStream(src+"1.png"));
                img2 = ImageIO.read(new FileInputStream(src+"2.png"));
                img3 = ImageIO.read(new FileInputStream(src+"3.png"));
                img4 = ImageIO.read(new FileInputStream(src+"4.png"));
                img5 = ImageIO.read(new FileInputStream(src+"5.png"));
                img6 = ImageIO.read(new FileInputStream(src+"6.png"));
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }

            int task = 1;
            double index = 42.5;
            String path = "";
            for (int i = 0; i < list.size(); i++) {
                System.out.println(Thread.currentThread().getName() + ": " + task + "/" + list.size());
                task++;

                if ((i + 1) % height == 0 || i == 0) {  //换列
                    if ((i + 1) % height == 0) {
                        i1 = i1 + 1;
                        i++;
                    }
                    if (list.get(i) <= index) {
                        path = src+"6.png";
                    } else if (list.get(i) <= index * 2) {
                        path = src+"5.png";
                    } else if (list.get(i) <= index * 3) {
                        path = src+"4.png";
                    } else if (list.get(i) <= index * 4) {
                        path = src+"3.png";
                    } else if (list.get(i) <= index * 5) {
                        path = src+"2.png";
                    } else if (list.get(i) <= index * 6) {
                        path = src+"1.png";
                    }
                }
                if (list.get(i + 1) <= index) {
                    path = imageMargeTest(path, i1, img6, false);
                } else if (list.get(i + 1) <= index * 2) {
                    path = imageMargeTest(path, i1, img5, false);
                } else if (list.get(i + 1) <= index * 3) {
                    path = imageMargeTest(path, i1, img4, false);
                } else if (list.get(i + 1) <= index * 4) {
                    path = imageMargeTest(path, i1, img3, false);
                } else if (list.get(i + 1) <= index * 5) {
                    path = imageMargeTest(path, i1, img2, false);
                } else if (list.get(i + 1) <= index * 6) {
                    path = imageMargeTest(path, i1, img1, false);
                }
            }
        }
    }

    static class replace2 extends Thread{ //水平线程类
        public int i; //开始图片
        public int len;//宽度

        public replace2(int i,int len) {
            this.i = i;
            this.len = len ;
        }

        @Override
        public void run(){
            BufferedImage img = null;
            for (int j = 1; j < len; j++) {
                try {
                    img = ImageIO.read(new FileInputStream(path + (i + j) + ".jpg"));
                    System.out.println(Thread.currentThread().getName()+":" + i + "/" + width);
                    imageMargeTest(path + i + ".jpg", i, img, true);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

    }

    public static String enter(String path) {

        long  startTime = System.currentTimeMillis();//计时开始
        List<Double> data = ReadRgb(path); //img为改写的图片
        int dataSize = data.size();//总数据大小
        int threadSize;//线程数据大小
        int threadNum = 2;//默认线程数
        int maxNum = 10;//最大线程数
        if (width % 2 != 0) { //偶数判断
            width++ ;
        }

        for (int i = maxNum; i>1 ; i--) { //判断可执行最大线程数
            if ((width % i ) == 0 ) {
                threadNum = i ;
                break;
            }
        }
        System.out.println("线程数：" + threadNum);
        if (dataSize % 2 != 0) { //偶数判断 方便分组
            threadSize = (dataSize + 1) / threadNum ;
        }
        else threadSize = dataSize  / threadNum ;

        List<Double> thread; //对应线程数据
        Thread[] group = new Thread[threadNum]; //垂直线程组
        int[] k = new int[threadNum]; //每个线程开头列 例:1-251-451-751

        int len = width/threadNum ; //数据宽度
        for (int i = 0; i < threadNum; i++) { //为每个线程载入数组
            thread= new ArrayList<>(threadSize);
            k[i] = i * len + 1 ;
            for (int j = 0; j < dataSize; j++) {
                if (j <= threadSize*(i+1) && j >= threadSize*(i)){
                    thread.add(data.get(j));
                }
            }
            group[i] = new replace(thread,k[i]); //加入线程组
        }

        for (Thread t:group) { //线程启动
            t.start();
        }
        for (Thread t:group) { //等待全部线程执行完毕
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        Thread[] group2 = new Thread[threadNum]; //水平线程组
        for (int i = 0; i < threadNum; i++) { //k 开始图片 ,len 数据宽度
            group2[i] = new replace2(k[i],len);
        }
        for (Thread t:group2) { //线程启动
            t.start();

        }
        for (Thread t:group2) { //等待全部线程执行完毕
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        for (int i = 1; i < threadNum; i++) { //合并最后threadNum张图片
            try {
                BufferedImage img = ImageIO.read(new FileInputStream(path + k[i] + ".jpg"));
                imageMargeTest(path+"1.jpg", 1, img, true);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        for (int i = 1; i < width; i++) { //删除程序生成的文件
            File Delete=new File(path + (i + 1) + ".jpg");
            Delete.delete();
        }

        long endTime = System.currentTimeMillis();//计时
        System.out.println("程序运行时间：" + (endTime - startTime)/1000 + "s");
        return path+"1.jpg";

    }
}
